home *** CD-ROM | disk | FTP | other *** search
-
-
- /****************************************************************************
- * POVHELP.C - version 1.0 - 1 July 1994
- *
- * This module implements the main DOS help reader.
- *
- * from Persistence of Vision Raytracer
- * Copyright 1994 Persistence of Vision Team
- * Copyright 1994 Christopher J. Cason.
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * POV-Ray files may also be obtained from ftp.uwa.edu.au in pub/povray.
- *
- * This program was written in its entirety by Christopher J. Cason.
- * Its use is freely and permanently granted to the POV-Team and POV users
- * under the conditions specified in POVLEGAL.DOC.
- *
- * Author : C. J. Cason (cjcason@yarrow.wt.uwa.edu.au, CIS 100032,1644)
- *
- *****************************************************************************/
-
- /*---------------------------------------------------------------------------*/
- /* NOTE : If you're porting this to another architecture, don't forget that */
- /* the POV-Help database stores words and dwords in LSB-first format. */
- /*---------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <mem.h>
- #include <string.h>
- #include <alloc.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <bios.h>
- #include <ctype.h>
- #include <dir.h>
- #include <stdarg.h>
- #include "help.h"
-
- #define MAX_REF 512
- #define MAX_FRAGMENT 16
- #define MAX_LINK 64
- #define VSIZE_Y 55
- #define VSIZE_X 128
- #define MAX_BOOKMARK 32
-
- #define TITLE 0x01
- #define COPYRIGHT 0x02
- #define AUTHOR 0x03
- #define FAQ 0x04
- #define HELP 0x05
- #define CONTENTS 0x100
-
- #define PRESERVE (preserve_formatting || code_fragment || line_drawing)
-
- #ifdef max
- #undef max
- #endif
-
- #ifdef min
- #undef min
- #endif
-
- #define max(a,b) ((int) (a) > (int) (b) ? (a) : (b))
- #define min(a,b) ((int) (a) < (int) (b) ? (a) : (b))
-
- #define ISALT(s) (strcmp (s, "ALT") == 0)
- #define ISCTL(s) (strcmp (s, "CTL") == 0 || strcmp (s, "CTRL") == 0)
-
- #define COLUMNS *(unsigned *) MK_FP (0x40, 0x4a)
- #define ROWSIZE (COLUMNS * 2)
-
- typedef struct
- {
- unsigned char start_vx ;
- unsigned char end_vx ;
- unsigned short id ;
- unsigned short start_vy ;
- unsigned short end_vy ;
- } viewer_reference ;
-
- typedef struct
- {
- unsigned char start_vx ;
- unsigned char end_vx ;
- unsigned short start_vy ;
- unsigned short end_vy ;
- unsigned short length ;
- unsigned long offset ;
- } viewer_code_fragment ;
-
- typedef struct
- {
- /* these first three entries must not be changed/moved */
- unsigned long section ;
- unsigned long section_length ;
- char is_appendix ;
- char number [16] ;
- char title [80] ;
- unsigned index ;
- } viewer_toc ;
-
- typedef struct
- {
- int line ;
- int column ;
- short reference ;
- short link_number ;
- short first_line ;
- unsigned number ;
- } bookmark ;
-
- int line = 0 ;
- int column = 0 ;
- char *title ;
- char blank [VSIZE_X] [2] ;
- char *reference_strings ;
- char **reference_string_index ;
- char *paste_ptr ;
- char paste_buffer [2048] ;
- char search_string [33] = "" ;
- short current_reference = -1 ;
- short current_code_fragment = -1 ;
- short link_number = -1 ;
- short first_line = 0 ;
- short wsize_y = 15 ;
- void far *pageframe ;
- unsigned x1 ;
- unsigned y1 ;
- unsigned x2 ;
- unsigned y2 ;
- unsigned emshandle ;
- unsigned shell ;
- unsigned base = 0xb800 ;
- unsigned paste = 0 ;
- unsigned home_wanted = 1 ;
- unsigned char attribute = 0x1f ;
- unsigned char reference ;
- unsigned char highlight ;
- unsigned char bold ;
- unsigned char code_fragment ;
- unsigned char heading ;
- unsigned char line_drawing ;
- unsigned char preserve_formatting ;
- unsigned char table ;
- unsigned char list ;
- unsigned char list_entry ;
- unsigned char wsize_x = 75 ;
- unsigned char left_margin ;
- unsigned char right_margin ;
- unsigned char *virtual_screen ;
- unsigned char *toc ;
- unsigned char saved_screen [6600] ;
- unsigned char *section ;
- unsigned char vx ;
- unsigned long links [MAX_LINK] ;
- unsigned long *reference_index ;
- unsigned long target_offset ;
- unsigned short vy ;
- unsigned short reference_count ;
- unsigned short code_fragment_count ;
- unsigned short TOCsize ;
- unsigned short ignore_lines = 0 ;
- unsigned short link_count ;
- unsigned short target_line ;
- unsigned short what_is_where [VSIZE_Y] [2] ;
- unsigned short poppeddown ;
- unsigned short mouseInstalled = 0 ;
- unsigned short justifyOn = 1 ;
- unsigned short current_bookmark = 0 ;
- FILE *inF ;
- bookmark bookmarks [MAX_BOOKMARK] ;
- viewer_toc tc ;
- viewer_reference *references ;
- help_file_header header ;
- viewer_code_fragment *code_fragments ;
-
- extern char scancodes [] ;
- extern unsigned running ;
- extern unsigned counter ;
- extern unsigned scancode ;
- extern unsigned scanflag ;
- extern unsigned popdown ;
-
- void kbinit (void) ;
- void deinit (void) ;
-
- void gotoxy (int x, int y)
- {
- _AH = 0x02 ;
- _DH = --y ;
- _DL = --x ;
- _BH = 0 ;
- geninterrupt (0x10) ;
- }
-
- unsigned astrlen (unsigned *s, unsigned width)
- {
- unsigned *s1 = s + width ;
-
- while ((char) *--s1 == ' ' && s1 > s) ;
- return ((unsigned) (s1 - s)) ;
- }
-
- unsigned wordcount (unsigned *s, unsigned width)
- {
- unsigned wc = 0 ;
- unsigned inword = 0 ;
-
- while (width--)
- {
- if (inword == 0)
- {
- if ((char) *s++ == ' ') continue ;
- inword++ ;
- wc++ ;
- }
- else
- {
- if ((char) *s++ != ' ') continue ;
- inword = 0 ;
- }
- }
- return (wc) ;
- }
-
- void insertspaces (unsigned howmany, unsigned *s, unsigned width)
- {
- unsigned *s1 = s + width ;
-
- while (howmany--)
- {
- while ((char) *--s1 == ' ' && s1 > s) ;
- if (s1 == s) return ;
- while ((char) *--s1 != ' ' && s1 > s) ;
- if (s1 == s) return ;
- memmove (s1 + 1, s1, (width - (unsigned) (s1 - s) - 1) * 2) ;
- }
- }
-
- void justify (unsigned *s, unsigned width)
- {
- int needed ;
- unsigned wc ;
-
- if ((needed = width - astrlen (s, width) - 1) <= 0) return ;
- if ((wc = wordcount (s, width)) == 0) return ;
- while (needed > wc)
- {
- insertspaces (needed, s, width) ;
- needed -= wc ;
- }
- insertspaces (needed, s, width) ;
- }
-
- unsigned translate_keycode (char *keycode)
- {
- char str [32] ;
- char *s ;
-
- strncpy (str, keycode, 31) ;
- if ((s = strtok (strupr (str), "-+")) == NULL) return (1) ;
- if (!ISALT (s) && !ISCTL (s)) return (1) ;
- scanflag = ISALT (s) ? ALT : CONTROL ;
- if ((s = strtok (NULL, "-+")) == NULL) return (1) ;
- if (ISALT (s) || ISCTL (s))
- {
- scanflag |= ISALT (s) ? ALT : CONTROL ;
- if ((s = strtok (NULL, "-+")) == NULL) return (1) ;
- }
-
- if (strcmp (strupr (s), "ESC") == 0) s = "\x1b" ;
- if (strlen (s) > 1 || (unsigned char) *s > 0x7f) return (1) ;
-
- scancode = scancodes [*s] ;
- return (0) ;
- }
-
- void far *emscalloc (unsigned items, unsigned count)
- {
- unsigned i ;
- union REGS regs ;
-
- if (shell == 0) return (farcalloc (items, count)) ;
-
- for (i = 0 ; i < 4 ; i++)
- {
- regs.h.ah = 0x44 ; /* map EMS page */
- regs.x.dx = emshandle ;
- regs.h.al = i ; /* physical page */
- regs.x.bx = i ; /* logical page */
- int86 (0x67, ®s, ®s) ;
- if (regs.h.ah != 0) return (NULL) ;
- }
-
- return (pageframe) ;
- }
-
- void emsfree (void *p)
- {
- if (shell == 0)
- {
- farfree (p) ;
- return ;
- }
- }
-
- unsigned emsinit (void)
- {
- FILE *f ;
- union REGS regs ;
-
- if ((f = fopen ("EMMXXXX0", "r")) == NULL) return (1) ;
- fclose (f) ;
- regs.h.ah = 0x46 ; /* get EMS manager version */
- int86 (0x67, ®s, ®s) ;
- if (regs.h.ah != 0) return (1) ;
- regs.h.ah = 0x40 ; /* get EMS manager status */
- int86 (0x67, ®s, ®s) ;
- if (regs.h.ah != 0) return (1) ;
- regs.h.ah = 0x41 ; /* get EMS page frame */
- int86 (0x67, ®s, ®s) ;
- if (regs.h.ah != 0) return (1) ;
- pageframe = MK_FP (regs.x.bx, 0) ;
- regs.h.ah = 0x43 ; /* get EMS handle and allocate memory */
- regs.x.bx = 4 ;
- int86 (0x67, ®s, ®s) ;
- if (regs.h.ah != 0) return (1) ;
- emshandle = regs.x.dx ;
- return (0) ;
- }
-
- void emsfinish (void)
- {
- union REGS regs ;
-
- regs.h.ah = 0x45 ; /* release EMS handle and memory */
- regs.x.dx = emshandle ;
- int86 (0x67, ®s, ®s) ;
- }
-
- unsigned emsstore (unsigned restore)
- {
- union REGS regs ;
- struct SREGS sregs ;
- static char store [256] ;
-
- if (restore == 0)
- {
- regs.x.ax = 0x4e00 ; /* get mapping registers */
- regs.x.di = FP_OFF (store) ;
- sregs.es = FP_SEG (store) ;
- int86x (0x67, ®s, ®s, &sregs) ;
- if (regs.h.ah != 0) return (1) ;
- }
- else
- {
- regs.x.ax = 0x4e01 ; /* set mapping registers */
- regs.x.si = FP_OFF (store) ;
- sregs.ds = FP_SEG (store) ;
- int86x (0x67, ®s, ®s, &sregs) ;
- if (regs.h.ah != 0) return (1) ;
- }
- return (0) ;
- }
-
- void mousestate (unsigned show)
- {
- union REGS regs ;
-
- if (mousestate == 0) return ;
- regs.x.ax = show ? 0x01 : 0x02 ;
- int86 (0x33, ®s, ®s) ;
- }
-
- void message_printf (char *format, ...)
- {
- static char str [140] ;
- char *s1 = str ;
- char far *s2 = MK_FP (base, (y2 + 1) * ROWSIZE + x1 * 2) ;
- unsigned i ;
- va_list arg_ptr ;
-
- va_start (arg_ptr, format) ;
- vsprintf (str, format, arg_ptr) ;
- va_end (arg_ptr) ;
-
- for (i = 0 ; i < wsize_x - 1 ; i++)
- {
- *s2++ = *s1 ? *s1++ : ' ' ;
- *s2++ = 0x0e ;
- }
- }
-
- unsigned message_gets (char *prompt, char *s, unsigned length)
- {
- char ch ;
- unsigned index = strlen (s) ;
- unsigned changed = 0 ;
-
- while (1)
- {
- message_printf ("%s : %s", prompt, s) ;
- gotoxy (x1 + strlen (prompt) + index + 4, y2 + 2) ;
- while (popdown == 0 && bioskey (0x11) == 0) geninterrupt (0x28) ;
- if (popdown) return (1) ;
- ch = bioskey (0x10) ;
- switch ((unsigned char) ch)
- {
- case '\r' :
- case '\n' :
- case '\x1b' : gotoxy (COLUMNS + 1, 50) ;
- message_printf ("") ;
- return (ch == 0x1b) ;
- case '\b' : if (index == 0) break ;
- s [--index] = '\0' ;
- changed++ ;
- break ;
- default : if (ch < 0x20 || ch > 0x7f) break ;
- if (index >= length) break ;
- if (changed++ == 0) index = 0 ;
- s [index++] = ch ;
- s [index] = '\0' ;
- break ;
- }
- }
- return (0) ;
- }
-
- void localdelay (unsigned milliseconds)
- {
- if (shell)
- {
- counter = milliseconds / 55 ;
- while (counter && counter--) ++counter ; /* make compiler happy ; it doesn't understand volatile */
- }
- else
- delay (milliseconds) ;
- }
-
- unsigned ustrcmp (char *s1, char *s2)
- {
- while (*s1 && *s2)
- if (toupper (*s1++) != toupper (*s2++))
- return (1) ;
- return (*s1 || *s2) ;
- }
-
- void frame (void)
- {
- unsigned x ;
- unsigned y ;
- unsigned *ptr ;
-
- x1 = (COLUMNS - wsize_x) / 2 - 1 ;
- y1 = (25 - wsize_y) / 2 - 2 ;
- x2 = x1 + wsize_x + 1 ;
- y2 = y1 + wsize_y + 1 ;
-
- ptr = MK_FP (base, y1 * ROWSIZE + x1 * 2) ;
- for (x = x1 ; x < x2 ; x++) *ptr++ = ('─\x0f') ;
- ptr = MK_FP (base, y2 * ROWSIZE + x1 * 2) ;
- for (x = x1 ; x < x2 ; x++) *ptr++ = ('─\x0f') ;
- ptr = MK_FP (base, (y2 + 2) * ROWSIZE + x1 * 2) ;
- for (x = x1 ; x < x2 ; x++) *ptr++ = ('─\x0f') ;
- for (y = y1 ; y < y2 + 2 ; y++)
- {
- *(unsigned *) MK_FP (base, y * ROWSIZE + x1 * 2) = '│\x0f' ;
- *(unsigned *) MK_FP (base, y * ROWSIZE + x2 * 2) = '│\x0f' ;
- }
- *(unsigned *) MK_FP (base, y1 * ROWSIZE + x1 * 2) = '┌\x0f' ;
- *(unsigned *) MK_FP (base, y1++ * ROWSIZE + x2 * 2) = '┐\x0f' ;
- *(unsigned *) MK_FP (base, y2 * ROWSIZE + x1 * 2) = '├\x0f' ;
- *(unsigned *) MK_FP (base, y2 * ROWSIZE + x2 * 2) = '┤\x0f' ;
- *(unsigned *) MK_FP (base, (y2 + 2) * ROWSIZE + x1++ * 2) = '└\x0f' ;
- *(unsigned *) MK_FP (base, (y2-- + 2) * ROWSIZE + x2-- * 2) = '┘\x0f' ;
- *(unsigned *) MK_FP (base, (y2 + 2) * ROWSIZE + x1++ * 2) = ' \x0f' ;
- *(unsigned *) MK_FP (base, (y2++ + 2) * ROWSIZE + x2++ * 2) = ' \x0f' ;
- y1++ ;
- left_margin = 0 ;
- right_margin = wsize_x ;
- gotoxy (COLUMNS + 1, 50) ;
- }
-
- void get_line (unsigned line, char *s)
- {
- char far *_s = MK_FP (base, line * ROWSIZE) ;
- unsigned i ;
-
- for (i = 0 ; i < COLUMNS ; i++)
- {
- *s++ = *_s++ ;
- _s++ ;
- }
- *s++ = '\x00' ;
- }
-
- void putwindow (unsigned column, unsigned line)
- {
- char *s2 = virtual_screen + line * VSIZE_X * 2 + column * 2 ;
- char far *s1 = MK_FP (base, (y1 - 1) * ROWSIZE + (x1 - 1) * 2) ;
- unsigned width2 = VSIZE_X * 2 ;
- unsigned width1 = wsize_x * 2 ;
- unsigned count ;
-
- for (count = 0 ; count < wsize_y ; count++)
- {
- memcpy (s1, (line + count < VSIZE_Y) ? (char *) s2 : (char *) blank, width1) ;
- s1 += ROWSIZE ;
- s2 += width2 ;
- }
- }
-
- void highlight_line (unsigned line, char attribute)
- {
- char *s = MK_FP (base, (y1 + line - 1) * ROWSIZE + (x1 - 1) * 2 + 1) ;
- unsigned count ;
-
- for (count = wsize_x ; count ; count--, s += 2) *s = attribute ;
- }
-
- void write_attribute (unsigned x1, unsigned y1, unsigned x2, unsigned y2, char attribute)
- {
- char *s = virtual_screen + y1 * VSIZE_X * 2 + x1 * 2 ;
- unsigned count = (y2 * VSIZE_X + x2) - (y1 * VSIZE_X + x1) ;
-
- if (y2 < y1) return ;
- if (y2 == y1 && x2 < x1) return ;
- while (count--)
- {
- *++s = attribute ;
- s++ ;
- }
- }
-
- void clear_attributes (void)
- {
- reference = highlight = bold = code_fragment = 0 ;
- heading = line_drawing = preserve_formatting = 0 ;
- table = list = list_entry = 0 ;
- }
-
- void set_attribute (void)
- {
- attribute = 0x1f ;
- if (code_fragment) attribute = 0x1a ;
- if (heading) attribute = 0x1c ;
- if (line_drawing) attribute = 0x1b ;
- if (list_entry) attribute = 0x1e ;
- if (bold) attribute = 0x2f ;
- if (highlight) attribute = 0x1e ;
- if (bold && highlight) attribute = 0x2e ;
- if (reference) attribute = 0x3f ;
- }
-
- viewer_reference *create_reference (unsigned short id)
- {
- if (reference_count == MAX_REF) return (NULL) ;
- references [reference_count].id = id ;
- return (references + reference_count++) ;
- }
-
- void clear_references (void)
- {
- reference_count = 0 ;
- }
-
- viewer_code_fragment *create_code_fragment (void)
- {
- if (code_fragment_count == MAX_FRAGMENT) return (NULL) ;
- return (code_fragments + code_fragment_count++) ;
- }
-
- void clear_code_fragments (void)
- {
- code_fragment_count = 0 ;
- }
-
- viewer_toc *getTC (unsigned index)
- {
- char *s ;
- static viewer_toc result ;
-
- if (index >= header.section_count + header.appendix_count) index = 0 ;
- s = toc + (unsigned) ((unsigned long) TOCsize * index) ;
- memcpy (&result, s, sizeof (TOC_entry)) ;
- s += sizeof (TOC_entry) ;
- strcpy (result.number, s) ;
- strcpy (result.title, s + header.sec_number_len) ;
- result.index = index ;
- return (&result) ;
- }
-
- viewer_toc *findTCfromOffset (unsigned long offset)
- {
- unsigned i ;
- static viewer_toc result ;
-
- for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
- {
- result = *getTC (i) ;
- if (result.section > offset) continue ;
- if (result.section + result.section_length <= offset) continue ;
- return (&result) ;
- }
- return (NULL) ;
- }
-
- char *get_section (viewer_toc *tc, unsigned number)
- {
- unsigned count ;
- unsigned char *section ;
-
- *tc = *getTC (number) ;
- fseek (inF, tc->section, SEEK_SET) ;
- if (tc->section_length + 1 > 65534U)
- {
- message_printf ("section too big for present allocation code") ;
- localdelay (1000) ;
- return (NULL) ;
- }
- if ((section = emscalloc ((unsigned) tc->section_length + 1, 1)) == NULL)
- {
- message_printf ("error - cannot allocate enough memory for section %s", tc->number) ;
- localdelay (1000) ;
- return (NULL) ;
- }
- if (fread (section, (unsigned) tc->section_length + 1, 1, inF) == 0)
- {
- message_printf ("could not read section") ;
- localdelay (1000) ;
- return (NULL) ;
- }
- count = (unsigned) tc->section_length ;
- while (section [count - 1] == '\n' || section [count - 1] == PARAGRAPH) count-- ;
- section [count] = '\0' ;
- return (section) ;
- }
-
- unsigned findSection (char *s)
- {
- unsigned i ;
- viewer_toc result ;
-
- for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
- {
- result = *getTC (i) ;
- if (ustrcmp (s, result.number)) continue ;
- return (i) ;
- }
- return (-1) ;
- }
-
- unsigned findTitle (char *s)
- {
- static char str [80] ;
- unsigned i ;
- viewer_toc result ;
-
- strupr (s) ;
- for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
- {
- result = *getTC (i) ;
- if (ustrcmp (s, result.title)) continue ;
- return (i) ;
- }
- for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
- {
- result = *getTC (i) ;
- strcpy (str, result.title) ;
- strupr (str) ;
- if (strstr (str, s) == NULL) continue ;
- return (i) ;
- }
- return (-1) ;
- }
-
- unsigned findKeyword (char *s)
- {
- unsigned i ;
-
- for (i = 0 ; i < header.reference_count ; i++)
- if (ustrcmp (s, reference_string_index [i]) == 0)
- return (i) ;
- return (-1) ;
- }
-
- unsigned virtual_screen_full (void)
- {
- return (vy >= VSIZE_Y) ;
- }
-
- void clear_virtual_screen (void)
- {
- char *s = virtual_screen ;
- unsigned count = (unsigned) VSIZE_X * VSIZE_Y ;
-
- vx = 0 ;
- vy = 0 ;
- left_margin = 0 ;
- right_margin = wsize_x ;
-
- while (count--)
- {
- *s++ = ' ' ;
- *s++ = attribute ;
- }
- }
-
- unsigned line_is_blank (unsigned line)
- {
- char *s = virtual_screen + line * VSIZE_X * 2 ;
- unsigned count = (unsigned) VSIZE_X ;
-
- while (count--)
- {
- if (*s != ' ') return (0) ;
- s += 2 ;
- }
- return (1) ;
- }
-
- void vputchar (unsigned char ch)
- {
- char *s ;
-
- if (vy >= VSIZE_Y) return ;
-
- switch (ch)
- {
- case '\r' :
- vx = 0 ;
- return ;
-
- case '\n' :
- vx = VSIZE_X ;
- break ;
-
- default :
- if (vx >= VSIZE_X) return ;
- if (ignore_lines) break ;
- s = virtual_screen + (unsigned) vy * VSIZE_X * 2 + vx * 2 ;
- *s++ = ch ;
- *s++ = attribute ;
- break ;
- }
-
- if (++vx >= VSIZE_X)
- {
- if (ch == '\n' || !PRESERVE)
- {
- vx = left_margin ;
- if (ignore_lines)
- {
- --ignore_lines ;
- return ;
- }
- if (++vy >= VSIZE_Y) vy = VSIZE_Y ;
- }
- }
- }
-
- void vputchar_attr (unsigned char ch, unsigned char attr)
- {
- unsigned char a = attribute ;
-
- attribute = attr ;
- vputchar (ch) ;
- attribute = a ;
- }
-
- void vputstr (char *s)
- {
- while (*s)
- vputchar (*s++) ;
- }
-
- void cvputstr (char *s, unsigned type)
- {
- static char str [256] ;
- char *s1 = str ;
- unsigned count ;
-
- for (count = 0 ;; s++)
- {
- if (*s == '\n' || *s == '\0')
- {
- what_is_where [vy] [0] = type ;
- vx = (wsize_x - min (wsize_x, count)) / 2 ;
- for (s1 = str ; count ; count--)
- vputchar (*s1++) ;
- vputchar ('\n') ;
- if (*s == '\0') break ;
- s1 = str ;
- continue ;
- }
- *s1++ = *s ;
- count++ ;
- }
- }
-
- unsigned pointcount (char *s)
- {
- unsigned count = 0 ;
-
- while (*s)
- if (*s++ == '.')
- count++ ;
- return (count) ;
- }
-
- void vcachechar (char ch)
- {
- char *s ;
- static char str [128] ;
- static unsigned count = 0 ;
-
- if (ch == '\0' || ch == ' ' || ch == '\t' || ch == '\n' || count == 128)
- {
- if (count / 2 > right_margin - vx)
- {
- if (justifyOn && !list)
- justify ((unsigned *) (virtual_screen + (unsigned) vy * VSIZE_X * 2), wsize_x) ;
- vputchar ('\n') ;
- }
- for (s = str ; count ; count -= 2, s += 2)
- if (*s != ' ' || vx != left_margin)
- vputchar_attr (s [0], s [1]) ;
- if (ch == '\0') return ;
- }
- if (PRESERVE)
- {
- vputchar (ch) ;
- return ;
- }
- str [count++] = ch ;
- str [count++] = attribute ;
- }
-
- void redraw_references (void)
- {
- char attribute ;
- unsigned i ;
- viewer_reference *r ;
-
- if (current_reference < 0) return ;
- for (i = 0, r = references ; i < reference_count ; i++, r++)
- {
- attribute = i == current_reference ? 0x4f : 0x3f ;
- write_attribute (r->start_vx, r->start_vy, r->end_vx, r->end_vy, attribute) ;
- }
- }
-
- void redraw_code_fragments (void)
- {
- char attribute ;
- unsigned i ;
- viewer_code_fragment *f ;
-
- if (current_code_fragment < 0) return ;
- for (i = 0, f = code_fragments ; i < code_fragment_count ; i++, f++)
- {
- attribute = i == current_code_fragment ? 0x6f : 0x1a ;
- write_attribute (f->start_vx, f->start_vy, f->end_vx, f->end_vy, attribute) ;
- }
- }
-
- void format_section (viewer_toc *tc, char *section)
- {
- unsigned id ;
- unsigned look_for_target = target_offset != 0 ;
- unsigned escape = 0 ;
- unsigned char *s ;
- viewer_reference *r ;
- viewer_code_fragment *f ;
-
- clear_attributes () ;
- set_attribute () ;
- clear_references () ;
- clear_code_fragments () ;
- clear_virtual_screen () ;
- ignore_lines = first_line ;
- target_line = 0 ;
- if (tc)
- {
- heading++ ;
- set_attribute () ;
- if (tc->is_appendix) vputstr ("APPENDIX ") ;
- vputstr (tc->number) ;
- vx = 17 ;
- vputstr (tc->title) ;
- heading = 0 ;
- vcachechar ('\n') ;
- vcachechar ('\n') ;
- set_attribute () ;
- }
-
- while (*section == '\n' || (unsigned char) *section == PARAGRAPH) section++ ;
-
- for (s = section ; *s ; s++)
- {
- if (virtual_screen_full ())
- {
- if (look_for_target)
- {
- first_line += vy ;
- clear_references () ;
- clear_code_fragments () ;
- clear_virtual_screen () ;
- }
- else
- break ;
- }
-
- if (look_for_target && s - section >= target_offset)
- {
- target_line = vy ;
- look_for_target = 0 ;
- }
-
- if (escape == 0)
- {
- switch (*s)
- {
- case ESCAPE :
- escape++ ;
- break ;
-
- case PARAGRAPH :
- vcachechar ('\n') ;
- vcachechar ('\n') ;
- break ;
-
- case INDENT :
- if (vx > 3) vcachechar ('\n') ;
- vx = 3 ;
- break ;
-
- case REFERENCE :
- id = *++s ;
- id += (unsigned) *++s * 256 ;
- r = create_reference (id) ;
- break ;
-
- case TARGET :
- break ;
-
- case REFERENCE_ON :
- if (r == NULL) break ;
- vcachechar ('\0') ;
- r->start_vx = vx ;
- r->start_vy = vy ;
- reference++ ;
- set_attribute () ;
- break ;
-
- case REFERENCE_OFF :
- if (r == NULL) break ;
- vcachechar ('\0') ;
- r->end_vx = vx ;
- r->end_vy = vy ;
- reference = 0 ;
- r = NULL ;
- set_attribute () ;
- break ;
-
- case HIGHLIGHT_ON :
- case HIGHLIGHT_OFF :
- highlight = *s == HIGHLIGHT_ON ;
- set_attribute () ;
- break ;
-
- case BOLD_ON :
- case BOLD_OFF :
- bold = *s == BOLD_ON ;
- set_attribute () ;
- break ;
-
- case CODE_ON :
- code_fragment++ ;
- set_attribute () ;
- vcachechar ('\0') ;
- if ((f = create_code_fragment ()) == NULL) break ;
- f->start_vx = vx ;
- f->start_vy = vy ;
- f->length = 0 ;
- f->offset = (unsigned long) s + 1 ;
- break ;
-
- case CODE_OFF :
- code_fragment = 0 ;
- set_attribute () ;
- vcachechar ('\0') ;
- if (f == NULL) break ;
- f->end_vx = vx ;
- f->end_vy = vy ;
- f->length = (unsigned long) ((unsigned long) s - f->offset) - 1 ;
- f = NULL ;
- break ;
-
- case HEADING_ON :
- case HEADING_OFF :
- heading = *s == HEADING_ON ;
- set_attribute () ;
- break ;
-
- case LINE_ON :
- case LINE_OFF :
- line_drawing = *s == LINE_ON ;
- set_attribute () ;
- vcachechar ('\0') ;
- break ;
-
- case PRESERVE_ON :
- case PRESERVE_OFF :
- preserve_formatting = *s == PRESERVE_ON ;
- set_attribute () ;
- vcachechar ('\0') ;
- break ;
-
- case TABLE_ON :
- case TABLE_OFF :
- table = *s == TABLE_ON ;
- set_attribute () ;
- break ;
-
- case LIST_ON :
- if ((list = *++s) == 1) list++ ;
- left_margin = list += 2 ;
- break ;
-
- case LIST_OFF :
- left_margin = list = 0 ;
- break ;
-
- case LIST_ENTRY_ON :
- list_entry++ ;
- vcachechar ('\0') ;
- set_attribute () ;
- vx = 2 ;
- break ;
-
- case LIST_ENTRY_OFF :
- list_entry = 0 ;
- vcachechar ('\0') ;
- set_attribute () ;
- vx = left_margin ;
- while (*s == ' ') s++ ;
- break ;
-
- default :
- vcachechar (*s) ;
- break ;
- }
- }
- else
- {
- vcachechar (*s) ;
- escape = 0 ;
- }
- }
- vcachechar ('\0') ;
- while (vy > 0 && line_is_blank (vy)) vy-- ;
- if (reference)
- {
- reference_count-- ;
- reference = 0 ;
- }
- target_offset = 0 ;
- redraw_references () ;
- redraw_code_fragments () ;
- }
-
- void format_top_menu (unsigned number_to_find)
- {
- unsigned i ;
- unsigned offset ;
- viewer_toc tc ;
-
- clear_attributes () ;
- set_attribute () ;
- clear_references () ;
- clear_virtual_screen () ;
- memset (what_is_where, 0, sizeof (what_is_where)) ;
- ignore_lines = number_to_find == 0 ? first_line : 32767 ;
- target_line = 0 ;
-
- vputstr ("\r\n") ;
- attribute = 0x1e ;
- cvputstr (title, TITLE) ;
- attribute = 0x1a ;
-
- cvputstr ("HELP ON HELP", HELP) ;
- cvputstr ("COPYRIGHT", COPYRIGHT) ;
- cvputstr ("AUTHORS", AUTHOR) ;
- cvputstr ("FREQUENTLY ASKED QUESTIONS", FAQ) ;
-
- vputstr ("\r\n") ;
- attribute = 0x1f ;
-
- for (i = 0 ; i < header.section_count + header.appendix_count ; i++)
- {
- if (number_to_find)
- ignore_lines = i < number_to_find ? 32767 : 0 ;
- if (i == header.section_count)
- {
- vputstr ("\r\n") ;
- attribute = 0x1a ;
- cvputstr ("*** APPENDICES ***", 0) ;
- attribute = 0x1f ;
- vputstr ("\r\n") ;
- }
- tc = *getTC (i) ;
- what_is_where [vy] [0] = CONTENTS ;
- what_is_where [vy] [1] = i ;
- offset = pointcount (tc.number) * 3 ;
- vx = offset ;
- vputstr (tc.number) ;
- vx = 17 + offset ;
- vputstr (tc.title) ;
- vputstr ("\r\n") ;
- }
- while (vy > 0 && line_is_blank (vy)) vy-- ;
- }
-
- void format_general_text (char *s)
- {
- clear_attributes () ;
- set_attribute () ;
- clear_references () ;
- clear_virtual_screen () ;
- memset (what_is_where, 0, sizeof (what_is_where)) ;
- ignore_lines = first_line ;
- target_line = 0 ;
-
- attribute = 0x1e ;
- cvputstr (s, 0) ;
- while (vy > 0 && line_is_blank (vy)) vy-- ;
- }
-
- void load_links (void)
- {
- unsigned child_count ;
-
- link_count = 0 ;
- link_number = -1 ;
- if (current_reference == -1) return ;
- fseek (inF, reference_index [references [current_reference].id], SEEK_SET) ;
- fread (&child_count, 2, 1, inF) ;
- if (child_count >= MAX_LINK - 1) child_count = MAX_LINK - 1 ;
- fread (links, 4, link_count = child_count + 1, inF) ;
- }
-
- void push_context (int number, short first_line, int line, int column, short current_reference, short link_number)
- {
- bookmark *bm = bookmarks + current_bookmark ;
-
- /*message_printf ("saved %d %d %d %d [%d]", number, first_line, line, column, current_bookmark) ;
- localdelay (1000) ; */
- if (current_bookmark >= MAX_BOOKMARK)
- {
- memcpy (bookmarks, bookmarks + 1, sizeof (bookmarks) - sizeof (bookmark)) ;
- bm-- ;
- }
- else
- current_bookmark++ ;
- bm->number = number ;
- bm->first_line = first_line ;
- bm->line = line ;
- bm->column = column ;
- bm->reference = current_reference ;
- bm->link_number = link_number ;
- }
-
- void pop_context (int *number, short *first_line, int *line, int *column, short *current_reference, short *link_number)
- {
- bookmark *bm ;
-
- if (current_bookmark == 0) return ;
- bm = bookmarks + --current_bookmark ;
- if (number) *number = bm->number ;
- if (first_line) *first_line = bm->first_line ;
- if (line) *line = bm->line ;
- if (column) *column = bm->column ;
- if (current_reference) *current_reference = bm->reference ;
- if (link_number) *link_number = bm->link_number ;
- /*message_printf ("restored %d %d %d %d [%d]", *number, *first_line, *line, *column, current_bookmark) ;
- localdelay (1000) ; */
- }
-
- void display (int *number, unsigned use_link, unsigned use_stack)
- {
- int ch ;
- short reference ;
- short code_fragment ;
- unsigned i ;
- unsigned child_count ;
- unsigned bounce_me = 0 ;
- unsigned temp ;
- viewer_toc *t ;
- viewer_reference *r ;
- viewer_code_fragment *f ;
-
- /* if use_stack is TRUE, restore our position from the position stack */
- /* if use_link is TRUE, 'number' is an index into the reference array */
- /* bounce_me is set internally to cause a jump to reference index 'number' */
- /* use_link takes precedence over use_stack */
-
- while (1)
- {
- line = column = 0 ;
- if (section) emsfree (section) ;
- if (use_link || bounce_me)
- {
- /* link_number is the currently selected link */
- link_number = 0 ;
- fseek (inF, reference_index [*number], SEEK_SET) ;
- fread (&child_count, 2, 1, inF) ;
-
- /* only support MAX_LINK children (links) */
- if (child_count >= MAX_LINK - 1) child_count = MAX_LINK - 1 ;
-
- /* retrieve the actual links from the file */
- fread (links, 4, link_count = child_count + 1, inF) ;
-
- /* find TOC entry for the section, working it out from the offset */
- if ((t = findTCfromOffset (links [0])) == NULL)
- {
- message_printf ("link 0 [%08lx] not found", links [0]) ;
- return ;
- }
-
- /* get the section ; the index is assigned to number */
- section = get_section (&tc, *number = t->index) ;
-
- /* no references or code fragments assigned */
- current_reference = current_code_fragment = -1 ;
-
- /* go to the first one */
- target_offset = links [0] - tc.section ;
-
- /* the first line to display is set to 0, so we display the top */
- first_line = column = 0 ;
- format_section (&tc, section) ;
-
- /* try to keep at least one line above the target if possible */
- line = target_line == 0 ? target_line : target_line - 1 ;
-
- /* if we would go off the end of the window buffer ... */
- if (line + wsize_y > VSIZE_Y)
- {
- first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- format_section (&tc, section) ;
- }
-
- /* try to be a bit helpful */
- message_printf ("link 1 of %d - [+ Next], [- Previous]", link_count) ;
- }
- else
- {
- /* were we popped down ? (i.e. did they exit with the hot key ?) */
- if (poppeddown == 0 && use_stack == 0)
- {
- /* assume 'number' is a table of contents index */
- if ((section = get_section (&tc, *number)) == NULL) return ;
- first_line = 0 ;
- }
- else
- {
- /* restore lots of hopefully useful stuff */
- pop_context (number, &first_line, &line, &column, ¤t_reference, &link_number) ;
- current_code_fragment = -1 ;
- section = get_section (&tc, *number) ;
- format_section (&tc, section) ;
- if (link_number != -1)
- message_printf ("link %d of %d - [+ Next], [- Previous]", link_number, link_count) ;
- }
- }
- bounce_me = poppeddown = 0 ;
- format_section (&tc, section) ;
- current_reference = current_code_fragment = -1 ;
- while (bounce_me == 0)
- {
- /* column and line are the x and y offsets of the upper left corner */
- putwindow (column, line) ;
- while (popdown == 0 && bioskey (0x11) == 0) geninterrupt (0x28) ;
- if (popdown)
- {
- emsfree (section) ;
- section = NULL ;
- return ;
- }
- ch = bioskey (0x10) ;
- switch ((unsigned char) ch)
- {
- case 0x00 :
- case 0xe0 :
- switch (ch = (unsigned char) (ch >> 8))
- {
- case 0x3b : /* F1 */
- push_context (*number, first_line, line, column, current_reference, link_number) ;
- if (use_link == 0) link_count = 0 ;
- first_line = line = column = 0 ;
- emsfree (section) ;
- section = get_section (&tc, *number = 0) ;
- current_reference = -1 ;
- current_code_fragment = -1 ;
- format_section (&tc, section) ;
- message_printf ("Press BACKSPACE to backtrack") ;
- break ;
-
- case 0x50 : /* down */
- if (line > (int) (vy - wsize_y)) break ;
- if (++line + wsize_y > VSIZE_Y)
- {
- first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- format_section (&tc, section) ;
- }
- break ;
-
- case 0x48 : /* up */
- if (line == 0 && first_line == 0) break ;
- if (--line <= 0 && first_line != 0)
- {
- first_line = max ((int) first_line - VSIZE_Y / 2, 0) ;
- line = VSIZE_Y / 2 ;
- format_section (&tc, section) ;
- }
- break ;
-
- case 0x4d : /* right */
- if (column < VSIZE_X - wsize_x) column++ ;
- break ;
-
- case 0x4b : /* left */
- if (column) column-- ;
- break ;
-
- case 0x51 : /* page down */
- if (line > (int) (vy - wsize_y)) break ;
- if ((line += wsize_y) >= VSIZE_Y - wsize_y)
- {
- first_line += VSIZE_Y / 2 ;
- format_section (&tc, section) ;
- line = max (line - VSIZE_Y / 2, 0) ;
- }
- break ;
-
- case 0x49 : /* page up */
- if (line < wsize_y)
- {
- if (first_line < VSIZE_Y / 2)
- {
- line += first_line ;
- first_line = 0 ;
- }
- else
- {
- first_line -= VSIZE_Y / 2 ;
- line += VSIZE_Y / 2 ;
- }
- format_section (&tc, section) ;
- }
- line = line >= wsize_y ? line - wsize_y : 0 ;
- break ;
-
- case 0x76 : /* control-page down */
- if (*number >= header.section_count + header.appendix_count - 1) break ;
- first_line = line = column = 0 ;
- /* if we used links, don't clear it so 'B' will still work */
- if (use_link == 0) link_count = 0 ;
- emsfree (section) ;
- section = get_section (&tc, ++*number) ;
- current_reference = -1 ;
- current_code_fragment = -1 ;
- format_section (&tc, section) ;
- message_printf ("%s %s %s", tc.is_appendix ? "APPENDIX" : "", tc.number, tc.title) ;
- break ;
-
- case 0x84 : /* control-page up */
- if (*number == 0) break ;
- first_line = line = column = 0 ;
- /* if we used links, don't clear it so 'B' will still work */
- if (use_link == 0) link_count = 0 ;
- emsfree (section) ;
- section = get_section (&tc, --*number) ;
- current_reference = -1;
- current_code_fragment = -1 ;
- format_section (&tc, section) ;
- message_printf ("%s %s %s", tc.is_appendix ? "APPENDIX" : "", tc.number, tc.title) ;
- break ;
-
- case 0x0f : /* shift-tab */
- if (reference_count == 0) break ;
- reference = current_reference ;
- for (i = 0, r = references + reference - 1 ; i < reference_count ; i++, r--)
- {
- if (reference-- < 0)
- {
- reference = reference_count - 1 ;
- r = references + reference ;
- }
- if (r->start_vx > column + wsize_x - 1) continue ;
- if (r->end_vx < column) continue ;
- if (r->start_vy > line + wsize_y - 1) continue ;
- if (r->end_vy < line) continue ;
- break ;
- }
- if (i == reference_count) break ;
- current_reference = reference ;
- load_links () ;
- message_printf ("%d link(s) for this reference - '+' for first", link_count) ;
- redraw_references () ;
- break ;
-
- case 0xa5 : /* Alt-Tab */
- if (code_fragment_count == 0) break ;
- code_fragment = current_code_fragment ;
- for (i = 0, f = code_fragments + code_fragment + 1 ; i < code_fragment_count ; i++, f++)
- {
- if (++code_fragment >= code_fragment_count)
- {
- code_fragment = 0 ;
- f = code_fragments ;
- }
- if (f->start_vx > column + wsize_x - 1) continue ;
- if (f->end_vx < column) continue ;
- if (f->start_vy > line + wsize_y - 1) continue ;
- if (f->end_vy < line) continue ;
- break ;
- }
- if (i == code_fragment_count) break ;
- current_code_fragment = code_fragment ;
- redraw_code_fragments () ;
- break ;
- }
- break ;
-
- case '\t' :
- if (reference_count == 0) break ;
- reference = current_reference ;
- for (i = 0, r = references + reference + 1 ; i < reference_count ; i++, r++)
- {
- if (++reference >= reference_count)
- {
- reference = 0 ;
- r = references ;
- }
- if (r->start_vx > column + wsize_x - 1) continue ;
- if (r->end_vx < column) continue ;
- if (r->start_vy > line + wsize_y - 1) continue ;
- if (r->end_vy < line) continue ;
- break ;
- }
- if (i == reference_count) break ;
- current_reference = reference ;
- load_links () ;
- message_printf ("%d link(s) for this reference - '+' for first", link_count) ;
- redraw_references () ;
- break ;
-
- case ' ' :
- if (*number >= header.section_count + header.appendix_count - 1) break ;
- first_line = line = column = 0 ;
- /* if we used links, don't clear it so 'B' will still work */
- if (use_link == 0) link_count = 0 ;
- emsfree (section) ;
- section = get_section (&tc, ++*number) ;
- current_reference = -1 ;
- current_code_fragment = -1 ;
- format_section (&tc, section) ;
- message_printf ("%s %s %s", tc.is_appendix ? "APPENDIX" : "", tc.number, tc.title) ;
- break ;
-
- case 's' :
- case 'S' :
- if (message_gets ("Enter search key", search_string, sizeof (search_string) - 1) == 0)
- {
- if ((temp = findKeyword (search_string)) < 0xffff)
- {
- push_context (*number, first_line, line, column, -1, link_number) ;
- *number = temp ;
- bounce_me++ ;
- }
- else
- {
- message_printf ("'%s' : not found", search_string) ;
- localdelay (1000) ;
- }
- }
- message_printf ("") ;
- break ;
-
- case '+' :
- case '-' :
- case '\r' :
- if (link_count == 0) break ;
- if ((char) ch == '-')
- {
- if (link_number < 0) break ;
- if (--link_number == -1)
- {
- pop_context (number, &first_line, &line, &column, ¤t_reference, &link_number) ;
- current_code_fragment = -1 ;
- emsfree (section) ;
- section = get_section (&tc, *number) ;
- format_section (&tc, section) ;
- link_number = -1 ;
- message_printf ("%d link(s) for this reference - '+' for first", link_count) ;
- break ;
- }
- }
- else
- {
- if (link_number == link_count - 1) break ;
- if (link_number == -1)
- push_context (*number, first_line, line, column, current_reference, link_number) ;
- link_number++ ;
- }
- if ((t = findTCfromOffset (links [link_number])) == NULL)
- {
- message_printf ("link %d [%08lx] not found", link_number, links [link_number]) ;
- break ;
- }
- emsfree (section) ;
- section = get_section (&tc, *number = t->index) ;
- current_reference = -1 ;
- current_code_fragment = -1 ;
- target_offset = links [link_number] - tc.section ;
- first_line = 0 ;
- format_section (&tc, section) ;
- line = target_line == 0 ? target_line : target_line - 1 ;
- column = 0 ;
- if (line + wsize_y > VSIZE_Y)
- {
- first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- format_section (&tc, section) ;
- }
- message_printf ("link %d of %d - [+ Next], [- Previous]", link_number + 1, link_count) ;
- break ;
-
- case 'j' :
- case 'J' :
- justifyOn = !justifyOn ;
- message_printf ("Justify %s", justifyOn ? "on" : "off") ;
- format_section (&tc, section) ;
- break ;
-
- case 'p' :
- case 'P' :
- if (shell == 0 || current_code_fragment == -1) break ;
- paste = min (code_fragments [current_code_fragment].length, sizeof (paste_buffer)) ;
- memcpy (paste_buffer, (char *) code_fragments [current_code_fragment].offset, paste) ;
- paste_ptr = paste_buffer ;
- emsfree (section) ;
- section = NULL ;
- popdown++ ;
- return ;
-
- case '\b' :
- if (current_bookmark == 0)
- {
- message_printf ("History stack empty") ;
- localdelay (1000) ;
- message_printf ("") ;
- break ;
- }
- pop_context (number, &first_line, &line, &column, ¤t_reference, &link_number) ;
- current_code_fragment = -1 ;
- emsfree (section) ;
- section = get_section (&tc, *number) ;
- format_section (&tc, section) ;
- link_number = use_link ? 0 : -1 ;
- message_printf ("Backtracked to section %s", tc.number) ;
- break ;
-
- case '\x1b' :
- emsfree (section) ;
- section = NULL ;
- return ;
-
- default :
- break ;
- }
- }
- }
- }
-
- void display_text (unsigned what)
- {
- int line = 0 ;
- int column = 0 ;
- int ch ;
- char *text ;
- char *s ;
- unsigned i ;
- unsigned long offset ;
- unsigned long length ;
-
- poppeddown = 0 ;
- switch (what)
- {
- case COPYRIGHT :
- offset = header.copyright ;
- length = header.copyright_length ;
- break ;
-
- case AUTHOR :
- offset = header.authors ;
- length = header.author_length ;
- break ;
-
- default :
- return ;
- }
-
- first_line = 0 ;
-
- if (length > 65534U)
- {
- message_printf ("section too big for present allocation code") ;
- localdelay (1000) ;
- return ;
- }
- if ((text = emscalloc ((unsigned) length + 1, 1)) == NULL)
- {
- message_printf ("cannot allocate memory for text") ;
- localdelay (1000) ;
- return ;
- }
- fseek (inF, offset, SEEK_SET) ;
- if (fread (text, (unsigned) length + 1, 1, inF) == 0)
- {
- message_printf ("could not read text") ;
- localdelay (1000) ;
- emsfree (text) ;
- return ;
- }
- text [(unsigned) length] = 0 ;
-
- for (s = text, i = (unsigned) length ; i ; i--, s++)
- if (*s == '\0')
- *s = '\n' ;
-
- if (what == AUTHOR)
- format_general_text (text) ;
- else
- format_section (NULL, text) ;
-
- message_printf (what == AUTHOR ? "List of Authors" : "Copyright information") ;
-
- while (1)
- {
- putwindow (column, line) ;
- while (popdown == 0 && bioskey (0x11) == 0) geninterrupt (0x28) ;
- if (popdown)
- {
- emsfree (text) ;
- return ;
- }
- switch ((char) (ch = bioskey (0x10)))
- {
- case 0x00 :
- case 0xe0 :
- switch (ch >> 8)
- {
- case 0x50 : /* down */
- if (line > (int) (vy - wsize_y)) break ;
- if (++line + wsize_y > VSIZE_Y)
- {
- first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- if (what == AUTHOR)
- format_general_text (text) ;
- else
- format_section (NULL, text) ;
- }
- break ;
-
- case 0x48 : /* up */
- if (line == 0 && first_line == 0) break ;
- if (--line == 0 && first_line != 0)
- {
- first_line = max ((int) first_line - VSIZE_Y / 2, 0) ;
- line = VSIZE_Y / 2 ;
- if (what == AUTHOR)
- format_general_text (text) ;
- else
- format_section (NULL, text) ;
- }
- break ;
-
- case 0x4d : /* right */
- if (column < VSIZE_X - wsize_x) column++ ;
- break ;
-
- case 0x4b : /* left */
- if (column) column-- ;
- break ;
-
- case 0x51 : /* page down */
- if (line > (int) (vy - wsize_y)) break ;
- if ((line += wsize_y) >= VSIZE_Y - wsize_y)
- {
- first_line += VSIZE_Y / 2 ;
- if (what == AUTHOR)
- format_general_text (text) ;
- else
- format_section (NULL, text) ;
- line = max (line - VSIZE_Y / 2, 0) ;
- }
- break ;
-
- case 0x49 : /* page up */
- if (line < wsize_y)
- {
- if (first_line < VSIZE_Y / 2)
- {
- line += first_line ;
- first_line = 0 ;
- }
- else
- {
- first_line -= VSIZE_Y / 2 ;
- line += VSIZE_Y / 2 ;
- }
- if (what == AUTHOR)
- format_general_text (text) ;
- else
- format_section (NULL, text) ;
- }
- line = line >= wsize_y ? line - wsize_y : 0 ;
- break ;
- }
- break ;
-
- case '\x1b' :
- emsfree (text) ;
- return ;
-
- default :
- break ;
- }
- }
- }
-
- void display_top_menu (int *number)
- {
- int column = 0 ;
- int ch ;
- int temp ;
- unsigned selection ;
- viewer_toc tc ;
- static int selected_line = 0 ;
- static int line = 0 ;
- static int local_first_line = 0 ;
-
- poppeddown = 0 ;
- first_line = local_first_line ;
- format_top_menu (0) ;
- while (selected_line < VSIZE_Y && what_is_where [selected_line] [0] < COPYRIGHT) selected_line++ ;
- if (selected_line >= wsize_y)
- {
- selected_line = wsize_y - 1 ;
- if (line <= (int) (vy - wsize_y))
- {
- if (++line + wsize_y > VSIZE_Y)
- {
- local_first_line = first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- format_top_menu (0) ;
- }
- }
- }
- while (1)
- {
- putwindow (column, line) ;
- selection = what_is_where [line + selected_line] [0] ;
- *number = what_is_where [line + selected_line] [1] ;
- switch (selection)
- {
- case AUTHOR :
- message_printf ("Press ENTER to list Authors") ;
- break ;
-
- case COPYRIGHT :
- message_printf ("Press ENTER for Copyright details") ;
- break ;
-
- case FAQ :
- message_printf ("Press ENTER to read FAQ") ;
- break ;
-
- case HELP :
- message_printf ("Press ENTER or F1 for HELP") ;
- break ;
-
- case CONTENTS :
- tc = *getTC (*number) ;
- message_printf ("%s", tc.title) ;
- break ;
-
- default :
- message_printf ("") ;
- break ;
- }
- highlight_line (selected_line, selection > TITLE ? 0x4f : 0x3f) ;
- while (popdown == 0 && bioskey (0x11) == 0) geninterrupt (0x28) ;
- if (popdown)
- {
- popdown = 0 ;
- return ;
- }
- switch ((char) (ch = bioskey (0x10)))
- {
- case 0x00 :
- case 0xe0 :
- switch (ch >> 8)
- {
- case 0x50 : /* down */
- if (++selected_line < wsize_y) break ;
- selected_line = wsize_y - 1 ;
- if (line > (int) (vy - wsize_y)) break ;
- if (++line + wsize_y > VSIZE_Y)
- {
- local_first_line = first_line += VSIZE_Y / 2 ;
- line = max (line - VSIZE_Y / 2, 0) ;
- format_top_menu (0) ;
- }
- break ;
-
- case 0x48 : /* up */
- if (--selected_line >= 0) break ;
- selected_line = 0 ;
- if (line == 0 && first_line == 0) break ;
- if (--line == 0 && first_line != 0)
- {
- local_first_line = first_line = max ((int) first_line - VSIZE_Y / 2, 0) ;
- line = VSIZE_Y / 2 ;
- format_top_menu (0) ;
- }
- selected_line = 0 ;
- break ;
-
- case 0x4d : /* right */
- if (column < VSIZE_X - wsize_x) column++ ;
- break ;
-
- case 0x4b : /* left */
- if (column) column-- ;
- break ;
-
- case 0x51 : /* page down */
- if (line > (int) (vy - wsize_y)) break ;
- if ((line += wsize_y) >= VSIZE_Y - wsize_y)
- {
- local_first_line = first_line += VSIZE_Y / 2 ;
- format_top_menu (0) ;
- line = max (line - VSIZE_Y / 2, 0) ;
- }
- break ;
-
- case 0x49 : /* page up */
- if (line < wsize_y)
- {
- if (first_line < VSIZE_Y / 2)
- {
- line += first_line ;
- first_line = 0 ;
- }
- else
- {
- local_first_line = first_line -= VSIZE_Y / 2 ;
- line += VSIZE_Y / 2 ;
- }
- format_top_menu (0) ;
- }
- line = line >= wsize_y ? line - wsize_y : 0 ;
- break ;
-
- case 0x3b : /* F1 */
- if ((*number = findTitle ("HELP ON HELP")) == -1) break ;
- message_printf ("Press SPACE for next section") ;
- display (number, 0, 0) ;
- first_line = local_first_line ;
- format_top_menu (0) ;
- break ;
- }
- break ;
-
- case '\r' :
- switch (selection)
- {
- case AUTHOR :
- case COPYRIGHT :
- display_text (selection) ;
- if (popdown)
- {
- popdown = 0 ;
- return ;
- }
- break ;
-
- case FAQ :
- if ((*number = findTitle ("FREQUENTLY ASKED QUESTIONS")) == -1) break ;
- message_printf ("Press SPACE for next section") ;
- display (number, 0, 0) ;
- if (popdown) return ;
- break ;
-
- case HELP :
- if ((*number = findTitle ("HELP ON HELP")) == -1) break ;
- message_printf ("Press SPACE for next section") ;
- display (number, 0, 0) ;
- if (popdown) return ;
- break ;
-
- case CONTENTS :
- display (number, 0, 0) ;
- if (popdown) return ;
- break ;
- }
- first_line = local_first_line ;
- format_top_menu (0) ;
- break ;
-
- case 's' :
- case 'S' :
- if (message_gets ("Enter search key", search_string, sizeof (search_string) - 1) == 0)
- {
- if ((temp = findKeyword (search_string)) != -1)
- {
- display (&temp, 1, 0) ;
- break ;
- }
- else
- {
- message_printf ("'%s' : not found", search_string) ;
- localdelay (1000) ;
- }
- }
- message_printf ("") ;
- break ;
-
- case '\x1b' :
- return ;
-
- default :
- break ;
- }
- }
- }
-
- unsigned load_strings (void)
- {
- char *s ;
- char str [81] ;
- unsigned i ;
- unsigned count ;
-
- if ((reference_strings = farcalloc ((unsigned) header.reference_string_length, 1)) == NULL) return (1) ;
- if ((reference_string_index = farcalloc (header.reference_count * 4, 1)) == NULL) return (1) ;
- s = reference_strings ;
- for (i = 0 ; i < header.reference_count ; i++)
- {
- fseek (inF, reference_index [i], SEEK_SET) ;
- fread (&count, 2, 1, inF) ;
- fseek (inF, (count + 1) * 4, SEEK_CUR) ;
- if (fgets (str, 80, inF) == NULL) break ;
- strcpy (s, str) ;
- reference_string_index [i] = s ;
- s += strlen (str) + 1 ;
- }
- return (0) ;
- }
-
- void init (void)
- {
- if ((references = calloc (sizeof (viewer_reference), MAX_REF)) == NULL)
- {
- printf ("cannot allocate memory for references\r\n") ;
- exit (1) ;
- }
- if ((code_fragments = calloc (sizeof (viewer_code_fragment), MAX_FRAGMENT)) == NULL)
- {
- printf ("cannot allocate memory for code fragments\r\n") ;
- exit (1) ;
- }
- if ((virtual_screen = calloc (VSIZE_X * 2, VSIZE_Y)) == NULL)
- {
- printf ("cannot allocate memory for virtual display\r\n") ;
- exit (1) ;
- }
- clear_virtual_screen () ;
- memcpy (blank, virtual_screen, VSIZE_X * 2) ;
- if ((toc = malloc ((unsigned) header.table_of_contents_length)) == NULL)
- {
- printf ("cannot allocate memory for table of contents\r\n") ;
- exit (1) ;
- }
- TOCsize = sizeof (TOC_entry) + header.sec_number_len + header.sec_title_len ;
- if ((reference_index = malloc ((unsigned) header.reference_index_length)) == NULL)
- {
- printf ("cannot allocate memory for reference index\r\n") ;
- exit (1) ;
- }
- fseek (inF, header.reference_index, SEEK_SET) ;
- if (fread (reference_index, (unsigned) header.reference_index_length, 1, inF) == 0)
- {
- printf ("could not read reference index\r\n") ;
- exit (1) ;
- }
- if ((title = calloc ((unsigned) header.title_length + 1, 1)) == NULL)
- {
- printf ("cannot allocate memory for title\r\n") ;
- exit (1) ;
- }
- fseek (inF, header.title, SEEK_SET) ;
- if (fread (title, (unsigned) header.title_length + 1, 1, inF) == 0)
- {
- printf ("could not read title\r\n") ;
- exit (1) ;
- }
- title [(unsigned) header.title_length] = 0 ;
- if (load_strings ())
- {
- printf ("could not load reference strings\r\n") ;
- exit (1) ;
- }
- }
-
- void popup (void)
- {
- int number = -1 ;
- int i ;
- char x ;
- char y ;
- char *s = "" ;
- char ch ;
- unsigned keyword_found = 0 ;
- union REGS regs ;
- static char str [133] ;
-
- mousestate (0) ;
- regs.h.ah = 0x03 ;
- regs.h.bh = 0 ;
- int86 (0x10, ®s, ®s) ;
- x = regs.h.dl ;
- y = regs.h.dh ;
- if (x < 0 || x > COLUMNS) x = 0 ;
- if (y < 0 || y > 50) y = 0 ;
-
- if (poppeddown == 0)
- {
- get_line (y, str) ;
- for (i = x ; i < COLUMNS && isalnum (str [i]) == 0 && str [i] != ' ' ; i++) ;
- while (--i >= 0)
- {
- if (isalnum (str [i])) continue ;
- switch (str [i])
- {
- case '_' :
- case '.' : continue ;
- }
- break ;
- }
- s = str + i + 1 ;
- while (++i < COLUMNS)
- {
- if (isalnum (str [i])) continue ;
- switch (str [i])
- {
- case '_' :
- case '.' : continue ;
- }
- break ;
- }
-
- str [i] = '\0' ;
- }
-
- memcpy (saved_screen, MK_FP (base, 0), sizeof (saved_screen)) ;
- frame () ;
- if (emsstore (0))
- {
- message_printf ("error in saving EMS page mapping") ;
- localdelay (1000) ;
- memcpy (MK_FP (base, 0), saved_screen, sizeof (saved_screen)) ;
- gotoxy (x, y) ;
- mousestate (1) ;
- return ;
- }
- if (*s)
- {
- if ((number = findKeyword (s)) != -1) keyword_found++ ;
- if (keyword_found == 0)
- if ((number = findKeyword (s + 1)) != -1)
- keyword_found++ ;
- if (keyword_found == 0)
- {
- ch = s [strlen (s) - 1] ;
- s [strlen (s) - 1] = '\0' ;
- if ((number = findKeyword (s)) != -1) keyword_found++ ;
- s [strlen (s)] = ch ;
- }
- if (keyword_found == 0)
- {
- if (number == -1) number = findTitle (s) ;
- if (number == -1) number = findSection (s) ;
- }
- }
-
- if (number != -1 || poppeddown)
- {
- message_printf (poppeddown ? "" : "searching on '%s'", s) ;
- display (&number, keyword_found, poppeddown) ;
- if (popdown == 0) display_top_menu (&number) ;
- }
- else
- display_top_menu (&number) ;
-
- if ((poppeddown = popdown) != 0)
- push_context (number, first_line, line, column, current_reference, link_number) ;
-
- if (emsstore (1))
- {
- for (i = 0 ; i < 5 ; i++)
- {
- message_printf ("WARNING !!! error in restoring EMS page mapping") ;
- localdelay (500) ;
- message_printf ("*** memory corruption possible !!! ***") ;
- localdelay (500) ;
- }
- }
- memcpy (MK_FP (base, 0), saved_screen, sizeof (saved_screen)) ;
-
- regs.h.ah = 0x02 ;
- regs.h.bh = 0 ;
- regs.h.dl = x ;
- regs.h.dh = y ;
- int86 (0x10, ®s, ®s) ;
- mousestate (1) ;
- }
-
- void Help (void)
- {
- printf ("\r\nPOVHELP : POV-Help reader for DOS\r\n\n") ;
- printf ("-i : set input file name (default HELP.PHE)\r\n") ;
- printf ("-w : set width of window\r\n") ;
- printf ("-h : set height of window\r\n") ;
- printf ("-ph[n] : send HOME key after each CR when pasting. default is -ph1\r\n") ;
- printf ("-j[-] : justify ON (default), -j- to turn off\r\n") ;
- printf ("-sX.Y : go to section X.Y\r\n") ;
- printf ("-tABC : go to first section with ABC in its title\r\n") ;
- printf ("-nn : go to the nth section (first = 0)\r\n") ;
- printf ("-kALT-H : set hotkey to ALT-H [CTRL, CTRL-ALT, A-Z, 0-9 permitted]\r\n") ;
- printf ("-eXYZ.EXE : run program XYZ.EXE (all subsequent params are passed to XYZ)\r\n") ;
- printf ("ABC : jump to first reference for keyword ABC\r\n") ;
- printf ("\r\n") ;
- printf ("POV-Help was written by Christopher J. Cason (cjcason@yarrow.wt.uwa.edu.au).\r\n") ;
- printf ("Converters are available which translate POV-Help databases to other formats\r\n") ;
- printf ("such as Postscript, LaTeX, RTF, Windows Help, HTML, etc.\r\n") ;
- printf ("The format of the POV-Help database is documentaed and freely available.\r\n") ;
- printf ("\r\n") ;
- printf ("POV-Help is free. It may not be sold. See POVLEGAL.DOC for details.\r\n") ;
- printf ("The POV-Help suite of programs is copyright (c) 1994 C. Cason and the POV-Team.\r\n") ;
- }
-
- unsigned main (unsigned argc, char *argv [])
- {
- int number = -1 ;
- char *s1 = "HELP.PHE" ;
- char gotoSection [16] = "" ;
- char gotoTitle [80] = "" ;
- char gotoKeyword [80] = "" ;
- char execName [128] = "" ;
- char keycode [32] = "ALT-ESC" ;
- char path [80] ;
- char drive [8] ;
- char dir [80] ;
- char name [16] ;
- char ext [8] ;
- char ch ;
- unsigned copyExec = 0 ;
- unsigned keyword_found = 0 ;
- union REGS regs ;
-
- regs.h.ah = 0x0f ;
- int86 (0x10, ®s, ®s) ;
- if ((regs.h.al & 0x7f) == 0x07) base = 0xb000 ;
-
- regs.x.ax = 0x21 ;
- int86 (0x33, ®s, ®s) ;
- mouseInstalled = regs.x.ax == 0xffff ;
-
- if ((inF = fopen (s1, "rb")) == NULL)
- {
- fnsplit (*argv, drive, dir, name, ext) ;
- fnmerge (path, drive, dir, "HELP", ".PHE") ;
- s1 = path ;
- }
- else
- fclose (inF) ;
-
- while (++argv, --argc)
- {
- if (copyExec == 0 && (**argv == '-' || **argv == '+'))
- {
- switch (toupper ((*argv) [1]))
- {
- case 'I' :
- s1 = *argv + 2 ;
- break ;
-
- case 'J' :
- justifyOn = (*argv) [2] != '-' ;
- break ;
-
- case 'N' :
- number = atoi (*argv + 2) ;
- break ;
-
- case 'W' :
- if (atoi (*argv + 2) == 0)
- {
- printf ("\r\n'%s' : invalid argument\r\n", *argv) ;
- Help () ;
- return (0) ;
- }
- wsize_x = max (25, min (127, atoi (*argv + 2))) ;
- break ;
-
- case 'H' :
- if ((*argv) [2] == '\0')
- {
- Help () ;
- return (0) ;
- }
- if (atoi (*argv + 2) == 0)
- {
- printf ("\r\n'%s' : invalid argument\r\n", *argv) ;
- Help () ;
- return (0) ;
- }
- wsize_y = max (5, min (21, atoi (*argv + 2))) ;
- break ;
-
- case 'S' :
- strncpy (gotoSection, *argv + 2, 15) ;
- break ;
-
- case 'T' :
- strncpy (gotoTitle, *argv + 2, 79) ;
- break ;
-
- case 'E' :
- strncpy (execName, *argv + 2, 127) ;
- fnsplit (execName, NULL, NULL, name, ext) ;
- if (strcmp (strupr (name), "EDIT") == 0 && strcmp (strupr (ext), ".COM") == 0)
- {
- printf ("\x07WARNING : POV-Help has a known incompatibility with DOS'S EDIT.COM\r\n") ;
- printf (" If this is the program you are trying to run, your system may crash.\r\n") ;
- printf ("Continue ? [y/N] : ") ;
- ch = getchar () ;
- if (toupper (ch) != 'Y') return (1) ;
- printf ("\r\n") ;
- }
- copyExec++ ;
- break ;
-
- case 'K' :
- strncpy (keycode, *argv + 2, 32) ;
- break ;
-
- case 'P' :
- if (toupper ((*argv) [2]) == 'H') home_wanted = 1 ;
- if (isdigit ((*argv) [3])) home_wanted = '0' - (*argv) [3] ;
- break ;
-
- case '?' :
- Help () ;
- return (0) ;
-
- default :
- printf ("unknown option '%s' [povhelp -? for help]\r\n", *argv) ;
- return (1) ;
- }
- }
- else
- if (copyExec)
- {
- strncat (execName, " ", 127) ;
- strncat (execName, *argv, 127) ;
- }
- else
- strncpy (gotoKeyword, *argv, 79) ;
- }
-
- if (keycode [0] != '\0')
- {
- if (translate_keycode (keycode))
- {
- printf ("invalid keycode string, '%s'\r\n", keycode) ;
- return (1) ;
- }
- }
-
- if ((inF = fopen (s1, "rb")) == NULL)
- {
- printf ("could not open input file '%s'\r\n", s1) ;
- return (1) ;
- }
- if (fread (&header, sizeof (help_file_header), 1, inF) == 0)
- {
- printf ("could not read header\r\n") ;
- return (1) ;
- }
-
- if (memcmp (header.signature, "POV-Help", 8) != 0)
- {
- printf ("header ID failed consistency check\r\n") ;
- return (1) ;
- }
-
- if (header.reader_version > VERSION)
- {
- printf ("version error ! database is not compatible [needs version %d.%d of reader]\r\n",
- header.reader_version / 100, header.reader_version % 100) ;
- return (1) ;
- }
-
- init () ;
-
- fseek (inF, header.table_of_contents, SEEK_SET) ;
- if (fread (toc, (unsigned) header.table_of_contents_length, 1, inF) == 0)
- {
- printf ("could not read table of contents\r\n") ;
- return (1) ;
- }
-
- if (*gotoTitle) number = findTitle (gotoTitle) ;
- if (*gotoSection) number = findSection (gotoSection) ;
- if (*gotoKeyword)
- if ((number = findKeyword (gotoKeyword)) != -1) keyword_found++ ;
-
- if (number < 0 && execName [0])
- {
- shell++ ;
- if (emsinit ())
- {
- printf ("could not initialise/allocate EMS for shell mode\r\n") ;
- return (1) ;
- }
- printf ("POV-Help v%d.%d - loading '%s' [use %s to pop up]\r\n",
- VERSION / 100, VERSION % 100, execName, keycode) ;
- kbinit () ;
- if (system (execName)) printf ("[could not execute command '%s']\r\n", execName) ;
- deinit () ;
- printf ("POV-Help - finished. (c) Christopher J. Cason/POV-Team 1994\r\n") ;
- emsfinish () ;
- shell-- ;
- }
- else
- {
- mousestate (0) ;
- clrscr () ;
- frame () ;
- if (number >= 0) display (&number, keyword_found, 0) ;
- display_top_menu (&number) ;
- gotoxy (1, 23) ;
- printf ("POV-Help v%d.%d - finished. (c) Christopher J. Cason/POV-Team 1994\r\n",
- VERSION / 100, VERSION % 100) ;
- mousestate (1) ;
- }
-
- farfree (reference_string_index) ;
- farfree (reference_strings) ;
- free (toc) ;
- free (virtual_screen) ;
- free (code_fragments) ;
- free (references) ;
- free (title) ;
- fclose (inF) ;
- return (0) ;
- }